﻿// 150. 括号画家.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>

/*
https://www.acwing.com/problem/content/152/
达达是一名漫画家，她有一个奇特的爱好，就是在纸上画括号。

这一天，刚刚起床的达达画了一排括号序列，其中包含小括号 ( )、中括号 [ ] 和大括号 { }，总长度为 N。

这排随意绘制的括号序列显得杂乱无章，于是达达定义了什么样的括号序列是美观的：

空的括号序列是美观的；
若括号序列 A 是美观的，则括号序列 (A)、[A]、{A} 也是美观的；
若括号序列 A、B 都是美观的，则括号序列 AB 也是美观的。
例如 [(){}]() 是美观的括号序列，而)({)[}]( 则不是。

现在达达想在她绘制的括号序列中，找出其中连续的一段，满足这段子串是美观的，并且长度尽量大。

你能帮帮她吗？

输入格式
输入一行由括号组成的字符串。

输出格式
输出一个整数，表示最长的美观的子段的长度。

数据范围
字符串长度不超过 105。

输入样例：
({({(({()}})}{())})})[){{{([)()((()]]}])[{)]}{[}{)
输出样例：
4
*/

#include <string>
#include <iostream>
#include <algorithm>
#include <stack>
#include <map>
using namespace std;

string str;

const int N = 100010;
int dp[N];

map<char, char> mm = { {')','('},{'}','{'},{']','['} };

int main() {
	cin >> str;
	str.insert(str.begin(), '#');
	stack<char> st; int ans = 0;
	for (int i = 1; i < str.size(); i++) {
		if (str[i] == ')' || str[i] == '}' || str[i] == ']') {
			if (!st.empty() && st.top() == mm[str[i]]) {
				st.pop(); dp[i] = dp[i - 1] + 2;
				int checkIdx = i - dp[i];
				if (checkIdx >= 1) { dp[i] += dp[checkIdx]; }
				ans = max(ans, dp[i]);
			}
			else { st.push('#'); }
		}
		else {
			st.push(str[i]);
		}
	}

	cout << ans << endl;

	return 0;
}
